/**
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 *   
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 */
package org.jiopi.ibean.loader.log;

import java.io.File;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.jiopi.ibean.loader.IBeanLoaderConstants;
import org.jiopi.ibean.share.ShareUtil.FileUtil;

/**
 * 
 * iBean客户端引导程序日志工具
 * 
 * @since 2010.4.12
 *
 */
public class LoaderLogUtil {
	
	private static volatile Logger loaderLogger = null;
	
	private static volatile boolean initialized = false;
	
	static{
		//初始化默认loaderLogger对象
		loaderLogger = Logger.getLogger( IBeanLoaderConstants.LOADER_NAME );
		loaderLogger.setUseParentHandlers( false );
		Handler cHandler = new ConsoleHandler();
		loaderLogger.addHandler( cHandler );
		Level setLevel = Level.parse(IBeanLoaderConstants.LOADER_LOG_LEVEL_DEFAULT);
		loaderLogger.setLevel(setLevel);
		cHandler.setLevel(setLevel);
	}
	
	
	/**
	 * 初始化日志保存目录<br/>
	 * 如果在得到Logger之前没有进行初始化,则只使用控制台输出,日志级别自动设置为INFO
	 * 初始化只能被进行一次,用于指定文件输出
	 * 
	 * @param workDir 工作目录
	 */
	public static void initialize(String workDir,String level){
		if(!initialized){
			synchronized(LoaderLogUtil.class){
				if(!initialized){
					try{
						Level setLevel = null;
						try {
							setLevel = Level.parse(level);
							loaderLogger.setLevel(setLevel);
						} catch (Exception e) {
							loaderLogger.setLevel(setLevel);
							logExceptionTrace(loaderLogger,Level.WARNING,null,"Bad level \""+level+"\",use default \""+IBeanLoaderConstants.LOADER_LOG_LEVEL_DEFAULT+"\"");
						}
						//设置已有Handler
						Handler[] handlers = loaderLogger.getHandlers();
						for(Handler handler:handlers){
							handler.setLevel(setLevel);
						}
						if(workDir!=null){//设置文件日志
							String logDirPath = FileUtil.joinPath(workDir, IBeanLoaderConstants.LOADER_LOG_DIR);
							File logDir = FileUtil.confirmDir(logDirPath,true);
							if(logDir!=null && logDir.canWrite()){
								String logFile = FileUtil.joinPath(logDirPath,IBeanLoaderConstants.LOADER_LOG_FILE);
								try {
									FileHandler fhandler = new FileHandler( logFile, 1024*1024*50, 50, true );
									fhandler.setFormatter(new LoaderLogFormatter());
									loaderLogger.addHandler(fhandler);
									fhandler.setLevel(setLevel);
									loaderLogger.config("Loader log will write to dir : "+logDir.getCanonicalPath());
								}catch (Exception e) {
									logExceptionTrace(loaderLogger,Level.WARNING,e,"Write Loader Log to File Error.");
								}
							}else{
								loaderLogger.config("Loader log will print to console only.");
							}
						}
					}finally{
						initialized = true;
					}
				}
			}
		}
	}
	
	
	/**
	 * 得到默认Loader的日志输出器
	 * @return
	 */
	public static Logger getLoaderLogger(){
		return loaderLogger;
	}
	
	
	public static Logger getLoaderLogger(String name){
		if(IBeanLoaderConstants.LOADER_NAME.equals(name)) return loaderLogger;
		Logger logger = Logger.getLogger(name);
		logger.setParent(loaderLogger);
		logger.setUseParentHandlers(true);
		return logger;
	}
	
	/**
	 * 
	 * 输出异常栈信息到日志
	 * 
	 * @param logger
	 * @param level 警告级别
	 * @param e
	 * @param msg 可选参数,文字内容
	 */
	public static void logExceptionTrace(Logger logger,Level level,Exception e,String... msg){
		
		if( e==null && msg.length <1) {
			return;
		}

		if( logger == null ) logger = getLoaderLogger(); 
		for(int i=0;i<msg.length;i++){
			logger.log(level, msg[i]);
		}
		if(e!=null) logger.log(level, e.toString(), e);

	}
	
}
